/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package view.GUI.listeners;

import controller.commands.AddNodeCommand;
import controller.commands.CloneCommand;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;
import javax.swing.JViewport;
import model.graphic.locations.AbsoluteLocation;
import model.graphic.locations.Location;
import view.GUI.sidepanels.TransferableArrayList;
import view.GUI.graphic.GraphicView;

/**
 *
 * @author Jelle
 */
public class DropListener implements DropTargetListener {

    private GraphicView gview;
    protected JPanel pane;
    protected DropTarget dropTarget;

    public DropListener(JPanel pane, GraphicView gview) {
        this.pane = pane;
        dropTarget = new DropTarget(pane, DnDConstants.ACTION_COPY_OR_MOVE, this, true, null);
        this.gview = gview;
    }

    public void dragEnter(DropTargetDragEvent dtde) {
    }

    public void dragExit(DropTargetEvent dte) {
    }

    public void dragOver(DropTargetDragEvent dtde) {
    }

    public void dropActionChanged(DropTargetDragEvent dtde) {
    }

    public static Location convertLocation(Point location, GraphicView gview){
        int xn = (int) (location.getX());
        int yn = (int) (location.getY());
        if (gview.isGridOn() && gview.isSnapped()) {
                xn = xn - xn % 25;
                yn = yn - yn % 25;
        }
        return new AbsoluteLocation(xn,yn);
    }

    public void drop(DropTargetDropEvent dtde) {
        if ((dtde.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE) != 0) {
            dtde.acceptDrop(dtde.getDropAction());
            Transferable tr = dtde.getTransferable();

            Point delta = ((JViewport)gview.getParent()).getViewPosition();
            Point location = dtde.getLocation();
            location.setLocation(location.getX() + delta.getX(), location.getY() + delta.getY());

            TransferableArrayList commands = new TransferableArrayList();
            DataFlavor FLAVOR = new DataFlavor(ArrayList.class, "commands");
            try {
                commands = (TransferableArrayList) tr.getTransferData(FLAVOR);
                for (Object d : commands) {
                    if (AddNodeCommand.class.isAssignableFrom(d.getClass())) {
                        AddNodeCommand anc = (AddNodeCommand) d;
                        anc.setLocation(convertLocation(location,gview));
                        gview.notifyObservers(anc);
                    } else if (CloneCommand.class.isAssignableFrom(d.getClass())) {
                        CloneCommand anc = (CloneCommand) d;
                        anc.setLocation(new AbsoluteLocation((int)location.getX(), (int)location.getY()));
                        gview.notifyObservers(anc);
                    }
                }
            } catch (UnsupportedFlavorException ex) {
                Logger.getLogger(DropListener.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(DropListener.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            
            dtde.dropComplete(true);
        }
    }

}

